#协程、greenlet、gevent、进线协对比

#一、协程介绍
'''
协程：单线程下的并发，又称为微简称，又叫纤程。Coroutine
是一种用户态轻量级线程。


协程是python中另外一种实现多任务的方式，只不过比线程更小
占用更小执行单元。为啥说它是一个执行单元，因为它自带CPU
上下文。这样只要在核实的时机，我们可以把一个协程切换到
另一个协程。只要这个过程中保存或恢复CPU上下那么程序还是
可以运行。



通俗理解：
在一个线程中的某个函数，可以在任何地方保存当前函数的一
些临时变量等信息，然后切换到另外一个函数中执行，注意不
是通过调用函数的方式做到，且切换的次数以及什么时候再切
换到原来的函数都由开发者自己确定。

协程能保留上一次调用时的状态。

线程和进程是通过CPU来调试

对于协程来说，程序员是上帝，你想让执行到哪里就执行到哪里



协程存在的意义：
多线程：分时切片，并发操作，线程切换需要耗时
协程：只使用一个线程，在一个线程中规定某个代码块执行顺序



应用场景：
IO特别多，因为python有GIL的存在，在同一时间内实际只有一个
现成在工作（IO操作保存状态，切换耗时），多线程的执行效率
比协程会更低。
在I/O特别多的情况下，协程的使用优于其他多任务完成方式。
'''



#使用yield创建协程
import time
def learn():
    while True:
        yield '好好学习'
        time.sleep(0.5)

def work():
    while True:
        yield '天天向上'

if __name__=='__main__':
    w1 = learn()
    w2 = work()
    while True:
        print(next(w1))
        print(next(w2))
        break
print('===================================================')
print('\n')




#greenlet (创建协程的第二种方式)
'''
为了更好使用协程来完成多任务，python中的greenlet模块对其
封装，从而使得切换任务变得更简单。

通过对象.switch()实现任务切换

'''
'''
from greenlet import greenlet
def eat():
    print('夜深了')
    print('可我还是忍不住想吃东西')

def shui():
    print('吃完了就食困')
    print('怎么办')

g1 = greenlet(eat)   #创建协程
g2 = greenlet(shui)

g1.switch()          #切换到g1来运行
g2.switch()
print('===================================================')
print('\n')
'''

#任务的任意切换
from greenlet import greenlet
def study():
    print('我真的准备')
    g2.switch()         #切换到g2任务执行
    print('要开始学习了')
    g2.switch()
def eat():
    print('要不')
             #切换到g1任务执行
    print('我还是先吃零食吧')

g1 = greenlet(study)    #创建协程
g2 = greenlet(eat)

g1.switch()             #切换到g1执行





